#include "syscall.h"
#include "usercommon.h"

int threadLockID;
int threadCV;
int threadsRunningMV;

void TestFork1_TestStack(int i)
{
	int tmp;
	if (i==-1)
		return;
	Acquire(threadLockID);

    printf_3("[TestFork1() User Function] Processing ", i, "\n");

	Release(threadLockID);
	TestFork1_TestStack(i-1);
	Acquire(threadLockID);

	printf_3("[TestFork1() User Function] Processed ", i, "\n");

	Release(threadLockID);
}

void TestFork1()
{
	int i = 0;
	Acquire(threadLockID);
		printf("[TestFork1() User Function] Started\n");
	Release(threadLockID);
	TestFork1_TestStack(20);
	Acquire(threadLockID);
		/*Signal(threadCV, threadLockID);*/
		threadsRunningMV--;
		printf("[TestFork1() User Function] Finished\n");
	Release(threadLockID);
	Exit(0);
}

void TestFork2_TestStack(char i)
{
	char toPrint[2];
	int tmp;
	if (i==('z'+ 1))
		return;
	toPrint[0] =i;
	toPrint[1] ='\0';
	Acquire(threadLockID);
	  printf("[TestFork2() User Function] Processing ");
	  printf(toPrint);
	  printf("\n");
	Release(threadLockID);
	TestFork2_TestStack(i+1);
	Acquire(threadLockID);
	  printf("[TestFork2() User Function] Processed ");
	  printf(toPrint);
	  printf("\n");
	Release(threadLockID);
}


void TestFork2()
{
	int i = 0;
	Acquire(threadLockID);
		printf("[TestFork2() User Function] Started\n");
	Release(threadLockID);
	TestFork2_TestStack('a');
	Acquire(threadLockID);
		/*Signal(threadCV, threadLockID);*/
		threadsRunningMV--;
		printf("[TestFork2() User Function] Finished\n");
	Release(threadLockID);
	Exit(0);
}


void TestFork3()
{
	int i = 0;
	Acquire(threadLockID);
		printf("[TestFork3() User Function] Started\n");
	Release(threadLockID);
	for (i = 1000; i <= 1100; i++)
	{
		Acquire(threadLockID);

		printf_3("[TestFork3() User Function] My order number is ", i, "\n");

		Release(threadLockID);
	}
	Acquire(threadLockID);
		/*Signal(threadCV, threadLockID);*/
		threadsRunningMV--;
		printf("[TestFork3() User Function] Finished\n");
	Release(threadLockID);
	Exit(0);
}


int main()
{
	int thread1_ID, thread2_ID, thread3_ID,  newProcessID;
	printLock = CreateLock("Printing Lock");
	threadLockID = CreateLock("myLock");
	threadCV = CreateCV("myCV");
	printf_5("[TEST SUITE] Created Lock#",threadLockID," and condition#",threadCV, " for thread testings\n");
	Acquire(threadLockID);
	printf("[TEST SUITE] Started Fork Test Suite.\n");
	printf("[TEST SUITE] Forking TestFork1()\n");
	thread1_ID = CallFork("TestFork1 Thread",(VoidFunctionPtr)TestFork1);
	printf("[TEST SUITE] Forking TestFork2()\n");
	thread2_ID = CallFork("TestFork2 Thread",(VoidFunctionPtr)TestFork2);
	printf("[TEST SUITE] Forking TestFork3()\n");
	thread3_ID = CallFork("TestFork3 Thread",(VoidFunctionPtr)TestFork3);
	Release(threadLockID);
	/*CallExec("homedepotentry");*/
	DestroyCV(threadCV);
	/*DestroyLock(threadLockID);
	DestroyLock(printLock);*/
	printf("[TEST SUITE] Finished Fork Test Suite.\n");
	Exit(0);
}
